#include <iostream>
#include "Key.h"

Key::Key()
          : data(NULL),
          size(0),
          offset(0)
{}

Key::Key(char* ptr, unsigned int s, long int off)
          : data(NULL),
          size(s),
          offset(off)
{
          if(ptr != NULL && s != 0)
          {
              if(data != NULL)
                      delete []data;
              data = new char[s];
              memcpy(data, ptr, s);
          }
}

//TODO verificar cuando llega toCopy!!!
Key::Key(const Key & toCopy)
          : data(NULL),
          size(toCopy.size),
          offset(toCopy.offset)
{
          if(&toCopy != NULL && toCopy.data != NULL && toCopy.size > 0)
          {
              if(data != NULL)
                      delete []data;
              data  = new char[toCopy.size];
              memset(data,0,toCopy.size);
              memcpy(data, toCopy.data, toCopy.size);
          }
	  else
		data = NULL;
}

Key::~Key()
{
           if(data != NULL)
                   delete []data;
	data = NULL; 
}

void Key::setKey(char* ptr, unsigned int s, long int o)
{
     if(ptr != NULL && s > 0)
     {
            if(data != NULL)
                    delete []data;	
            data = new char[s];
            memcpy(data, ptr, s);
            size = s;
            offset = o;           
     }
}

void Key::getKey(char* ptr, unsigned int &s)
{
     if(data != NULL && ptr != NULL)
     {
            memcpy(ptr, data, size);
            s = size;
     }
     else
         s = 0;
}

void Key::setOffset(long int o){

	offset = o;
}

long int Key::getOffset(){

	return offset;
}

unsigned int Key::getSize(){
    return size + sizeof(unsigned int) + sizeof(long int);
}

void Key::toCharArray(char* array, unsigned int &arraySize){
	if(array != NULL)
	{
		if(data != NULL && size != 0)
		{
			char* current = array;
			((unsigned int*)current)[0] = size;
			current += sizeof(unsigned int);
			memcpy(current, data, size);
			arraySize = size + sizeof(unsigned int);
		}
	}
	else
		std::cout << "TERRIBLE ERROR, NO LO PUDO PASAR A UN STREAM DE BYTES" << std::endl;
}

bool Key::operator==(const Key & der)const {
     if(data != NULL && size != 0 && der.data != NULL && der.size != 0)
             return (memcmp(data, der.data, (size < der.size) ? size : der.size) == 0);             
     else
          return false; 
}

bool Key::operator!=(const Key & der)const {
     return !(*this == der);     
}

bool Key::operator<(const Key & der)const {
	
	// Chequear que si es distinto de char* no va a funcionar
	// pasar void* -> char*
    if(data != NULL && size != 0 && der.data != NULL && der.size != 0){
    	std::string aux;
    	aux.append((char*)der.data,der.size);
    	std::string aux2;
    	aux2.append((char*)data,size);
        if (NumberUtil::isNumber(aux)==1 && NumberUtil::isNumber(aux2)==1){
        	double d1 = atof(aux.c_str());
        	double dThis = atof(aux2.c_str());
        	return (dThis < d1);
        }else{
        	return (memcmp(data, der.data, (size < der.size) ? size : der.size) < 0);  
        }
    }
     else
          return false;
}

bool Key::operator>(const Key & der)const {
	// Chequear que si es distinto de char* no va a funcionar
	// pasar void* -> char*
    if(data != NULL && size != 0 && der.data != NULL && der.size != 0){
    	std::string aux;
    	aux.append((char*)der.data,der.size);
    	std::string aux2;
    	aux2.append((char*)data,size);
        if (NumberUtil::isNumber(aux)==1 && NumberUtil::isNumber(aux2)==1){
        	double d1 = atof(aux.c_str());
        	double dThis = atof(aux2.c_str());
        	return (dThis > d1);
        }else{
        	return (memcmp(data, der.data, (size < der.size) ? size : der.size) > 0);  
        }
    }
     else
          return false;
}
const Key &Key::operator=(const Key& der){
     
     if(&der != this)
     {
             if(&der != NULL && der.data != NULL && der.size > 0)
             {
                  if(data != NULL)
                          delete []data;
                  data = new char[der.size];
                  memcpy(data, der.data, der.size);
                  size = der.size;
                  offset = der.offset;
              }
     }
     
     return (*this);
}


void Key::print()
{
	if(data != NULL && size > 0)
	{
 		char cad[300] = {0};
 		memcpy(cad, data, size);
 		cad[size] = '\0';
		std::cout << "Size: " << size << "  \t\t\t Offset: " << offset << "\t\t\t Data: " << cad << std::endl;
	}
	else
		std::cout << "La clave esta vacia" << std::endl;
}

void Key::clean()
{
	if(data != NULL)
		delete []data;
	data = NULL;
}




